﻿//
//write by sunware
//
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace PIM_ATE.Electrical
{
    public class clsBaseInstr
    {
        protected bool m_isDebug = false;
        protected int MaxTimeOut = 60000;//仪表默认超时时间秒
        public int m_vi;
        int m_viRM;
        bool m_isConnected = false;
        public StringBuilder m_sbErr = new StringBuilder(512);

        public string m_sClsType = "";
        public string m_sAddr = "";
        public clsBaseInstr()
        {
            m_isDebug = GDefine.IS_VNA_DEBUG_TEST;
        }

        public bool IsConnected()
        {
            return m_isConnected;
        }

        protected int GetErrNo(string sResult)
        {
            try
            {
                string[] sArray;
                sArray = sResult.Split(',');
                if (sArray.Length < 1)
                {
                    return -1;
                }
                return (int)Convert.ToSingle(sArray[0]);
            }
            catch (Exception ex)
            {
                this.m_sbErr.Append(ex.Message);
                return 0;
            }
        }

        //获取当前仪表的错误信息//函数返回是否有错误
        private bool GetSysErr(StringBuilder sbOutErr)
        {
            StringBuilder sbErr = new StringBuilder(512);
            bool bSysErr = false;
            int iErr, iReadCount = 0, nError = 1;
            //StringBuilder sbResult = new StringBuilder();
            byte[] buf = new byte[256];
            while (nError != 0)
            {
                iErr = visa32.viQueryf(m_vi, "%s\n", "%#t", "SYST:ERR?", out iReadCount, buf);
                //iErr = visa32.viQueryf(m_vi, "SYST:ERR?\n", "%t", buf);
                if (iErr < visa32.VI_SUCCESS)
                {
                    visa32.viStatusDesc(m_vi, iErr, sbErr);
                    sbOutErr.Append(sbErr + "\r\n");
                    return true;
                }

                string sRt = System.Text.Encoding.Default.GetString(buf);
                nError = GetErrNo(sRt);
                if (nError == 0)
                {//no err msg
                    return bSysErr;
                }
                else
                {
                    sbOutErr.Append(sRt);
                    bSysErr = true;
                }
            }
            return false;//没有错误
        }

        private bool Instr_OPC()
        {//判断当前仪表是否执行成功
            byte[] buf = new byte[256];
            int nReady;
            StringBuilder sbErr = new StringBuilder(512);
            int iReadCount = 0;
            //OPC不需要改延时，直接由外部决定
            //visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, GDefine.MaxTimeOut*2);//OPC最大延时30秒
            int iErr = visa32.viQueryf(m_vi, "%s\n", "%#t", "*OPC?", out iReadCount, buf);
            //visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, GDefine.MaxTimeOut);//还原最大延时
            //iErr = visa32.viQueryf(m_vi, "*OPC?\n", "%t", buf);
            if (iErr < 0)
            {
                visa32.viStatusDesc(m_vi, iErr, sbErr);
                this.m_sbErr.Append(sbErr + "\r\n");
                return false;
            }
            else
            {
                string sRt = System.Text.Encoding.Default.GetString(buf);
                nReady = GetErrNo(sRt);
            }
            if (nReady == 1)
                return true;
            else
            {
                return !GetSysErr(sbErr);
            }
        }

        //执行仪表命令//返回仪表错误 //并根据需要检查命令是否需要等待成功执行
        protected bool SendCmd(string command, StringBuilder sbOutErr, bool bNeedOPC)
        {
            if (m_isDebug) return true;
            StringBuilder sbErr = new StringBuilder(512);
            int iErr = visa32.viPrintf(m_vi, command);
            //Thread.Sleep(500);
            if (iErr < visa32.VI_SUCCESS)
            {
                visa32.viStatusDesc(m_vi, iErr, sbErr);
                sbOutErr.Append(sbErr + "\r\n");
                return false;
            }
            if (bNeedOPC)//如果需要检查命令是否成功执行
            {
                Instr_OPC();
            }
            return !GetSysErr(sbOutErr);
        }

        //执行查询仪表命令//返回仪表错误 //并根据需要检查命令是否需要等待成功执行
        public bool QueryCmd(string command, byte[] readBuf, StringBuilder sbOutErr, bool bNeedOPC)
        {
            if (m_isDebug) return true;
            StringBuilder sbErr = new StringBuilder(512);
            int iReadCount = 0x8000;
            int iErr = visa32.viQueryf(m_vi, "%s\n", "%#t", command, out iReadCount, readBuf);//m_vi, command, "%t", readBuf);
            //Thread.Sleep(500);
            if (iErr < visa32.VI_SUCCESS)
            {
                visa32.viStatusDesc(m_vi, iErr, sbErr);
                sbOutErr.Append(sbErr + "\r\n");
                return false;
            }
            if (bNeedOPC)//如果需要检查命令是否成功执行
            {
                Instr_OPC();
            }
            return !GetSysErr(sbOutErr);
        }

        public bool OpenDefaultRM(string addr)
        {
            if (m_isDebug) return true;
            try
            {
                m_sAddr = addr;
                this.m_sbErr.Length = 0;
                int iErr = visa32.viOpenDefaultRM(out m_viRM);
                if (iErr < visa32.VI_SUCCESS)
                {
                    visa32.viStatusDesc(m_vi, iErr, m_sbErr);
                    visa32.viClose(m_viRM);
                    this.m_isConnected = false;
                    return false;
                }
                //mustdo delete
                //this.m_isConnected = true;
                //return true;


                iErr = visa32.viOpen(m_viRM, addr, visa32.VI_NULL, visa32.VI_NULL, out m_vi);
                if (iErr != visa32.VI_SUCCESS)
                {
                    visa32.viStatusDesc(m_vi, iErr, m_sbErr);
                    visa32.viClose(m_viRM);
                    this.m_isConnected = false;
                    return false;
                }
                StringBuilder sbAttrValue = new StringBuilder(256);
                visa32.viGetAttribute(m_vi, visa32.VI_ATTR_RSRC_CLASS, sbAttrValue);
                visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TERMCHAR_EN, 1);
                visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, MaxTimeOut);//最大延时10秒

                //int s = visa32.viGetAttribute(m_vi, visa32.VI_ATTR_RSRC_CLASS, sbAttrValue);
                //s = visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, GDefine.MaxTimeOut);
                //if (sbAttrValue.ToString() == "INSTR")
                //{

                //}
                //else if (sbAttrValue.ToString() == "SOCKET")
                //{
                //    s = visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TERMCHAR_EN, visa32.VI_TRUE);
                //}
                //else
                //    MessageBox.Show(sbAttrValue.ToString() + ": RSRC_CLASS error!");

                this.m_isConnected = true;
                return true;
            }
            catch (Exception ex)
            {//一般由于visa32.dll引起
                System.Windows.Forms.MessageBox.Show(ex.Message);
                this.m_sbErr.Append(ex.Message);
                this.m_isConnected = false;
                return false;
            }
        }

        public bool Close()
        {
            if (m_isDebug) return true;
            visa32.viClose(m_vi);
            visa32.viClose(m_viRM);
            this.m_isConnected = false;
            return true;
        }
    }












    public class clsBaseVNA : clsBaseInstr
    {
        public int IFBandWidth = 3000;
        bool isSwitchOn = true;

        int chanNo = 1;
        int m_traceNo = 1;
        public clsBaseVNA()
        {
        }

        public clsBaseVNA(int IFB, bool isSwitchOn)
        {
            this.IFBandWidth = IFB;
            this.isSwitchOn = isSwitchOn;
        }


        public virtual void Dothings()
        {
            Console.WriteLine("this is in clsBaseVNA.");
        }

        public string GetIDN()
        {//得到trace 里面的smoothing 状态
            if (m_isDebug) return "";
            m_sbErr.Length = 0;
            m_sbErr.Append("GetIDN:");
            byte[] buf = new byte[256];
            if (!QueryCmd("*IDN?", buf, m_sbErr, false))
            {
                return "";
            }
            string sSmooth = System.Text.Encoding.Default.GetString(buf).TrimEnd(new char[] { '\n', '\0' });
            return sSmooth;
        }

        public bool SaveToReg(string regName)
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SaveToReg:");
            if (!SendCmd("MMEM:STOR:STYP CST" + "\n", m_sbErr, false))
            {
                return false;
            }
            if (!SendCmd("MMEM:STOR " + "\"" + regName + ".sta" + "\"" + "\n", m_sbErr, false))
            {
                return false;
            }

            int iErr = visa32.viPrintf(m_vi, "MMEM:STOR:STYP CST" + "\n");
            // 'CheckError viPrintf(m_vi, "MMEM:STOR " & Chr$(34) & "ATE/" & regName & ".sta" & Chr$(34) & Chr$(10), 0)
            iErr = visa32.viPrintf(m_vi, "MMEM:STOR " + "\"" + regName + ".sta" + "\"" + "\n");
            Thread.Sleep(500);
            /*
                        if (!SetContSweep())
                        {
                            return false;
                        }*/
            return true;

        }

        public bool LoadSegm(string sName)
        {//:MMEM:LOAD:SEGM "D:SEGM/SEGM01.CSV"  //:MMEM:STOR:SEGM "D:SEGM/SEGM01.CSV" 
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("LoadSegm:");
            return SendCmd("MMEM:LOAD:SEGM " + "\"" + sName + "\"\n", m_sbErr, false);
        }

        public bool SetSegmTable(string sSegmTable)
        {//+5.00000000000E+000,+0.00000000000E+000,+1.00000000000E+000,+1.00000000000E+000,+0.00000000000E+000,+0.00000000000E+000,+3.00000000000E+000,
            //+3.00000000000E+005,+1.70000000000E+009,+3.20100000000E+003,+1.00000000000E+004,+1.00000000000E+001,
            //+1.70000000000E+009,+3.00000000000E+009,+3.20100000000E+003,+5.00000000000E+002,+1.00000000000E+001,
            //+3.00000000000E+009,+8.50000000000E+009,+3.20100000000E+003,+1.00000000000E+004,+1.00000000000E+001
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetSegmTable:");
            return SendCmd(":SENS1:SEGM:DATA " + sSegmTable + "\n", m_sbErr, false);
        }

        public bool RecallReg(string regName)
        {
            if (m_isDebug) return true;
            //int iErr = visa32.viPrintf(m_vi, "MMEM:LOAD " + "\"" + regName + ".sta" + "\"" + "\n");
            //Thread.Sleep(200);
            m_sbErr.Length = 0;
            m_sbErr.Append("RecallReg:" + regName + ":");
            return SendCmd("MMEM:LOAD " + "\"" + regName + ".sta" + "\"" + "\n", m_sbErr, true);
        }

        public void DisplayUpdate(bool bEnable)
        {
            if (m_isDebug) return;
            if (bEnable)
                visa32.viPrintf(m_vi, ":DISP:ENAB ON" + "\n");
            else
                visa32.viPrintf(m_vi, ":DISP:ENAB OFF" + "\n");
        }

        public bool SetECalKit()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetECalKit:");
            visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, MaxTimeOut * 4);//校准时改变最大延时为120秒
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:ECAL:SOLT2 " + " 1,2" + "\n", m_sbErr, true);
            visa32.viSetAttribute(m_vi, visa32.VI_ATTR_TMO_VALUE, MaxTimeOut);
            return bRet;
            //int iErr = visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:ECAL:SOLT2 " + " 1,2" + "\n");
            //Thread.Sleep(7000);
        }

        public bool DisplayAutoScale()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("DisplayAutoScale:");
            return SendCmd(":DISP:WIND1:TRAC1:Y:AUTO\n", m_sbErr, false);
        }

        public bool DisplayAutoScaleAll()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("DisplayAutoScaleAll:");
            if (!SendCmd(":DISP:WIND1:TRAC1:Y:AUTO\n", m_sbErr, true))
            {
                return false;
            }
            if (!SendCmd(":DISP:WIND1:TRAC2:Y:AUTO\n", m_sbErr, true))
            {
                return false;
            }
            if (!SendCmd(":DISP:WIND1:TRAC3:Y:AUTO\n", m_sbErr, true))
            {
                return false;
            }
            if (!SendCmd(":DISP:WIND1:TRAC4:Y:AUTO\n", m_sbErr, true))
            {
                return false;
            }
            return true;
        }



        public bool TrigSingle()
        {
            if (m_isDebug) return true;
            //清除标志
            if (!SendCmd("*CLS" + "\n", m_sbErr, true))
            {
                return false;
            }
            //先触发
            return SendCmd("TRIG:SING" + "\n", m_sbErr, true);
        }

        public bool BeforeTrig()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("BeforeTrig:");
            if (!SendCmd("TRIG:SOUR BUS" + "\n", m_sbErr, true))
            {//TRIG:SOUR Internal  系统触发
                return false;
            }
            if (!SendCmd("INIT" + chanNo.ToString() + ":CONT ON" + "\n", m_sbErr, true))
            {
                return false;
            }
            return true;
        }

        public bool ReadFdata(int iTraceNo, ref StringBuilder sbRet)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("ReadFdata:");
            int maxCount = 1024, retCount = 0;
            byte[] byteRead = new byte[maxCount];
            int iErr = 0;
            iErr = visa32.viPrintf(m_vi, ":CALC1:PAR" + iTraceNo.ToString() + ":SEL\n");
            iErr = visa32.viPrintf(m_vi, ":CALC1:DATA:FDAT?\n");
            if (iErr < visa32.VI_SUCCESS)
            {
                visa32.viStatusDesc(m_vi, iErr, m_sbErr);
                return false;
            }

            iErr = visa32.VI_SUCCESS_MAX_CNT;
            while (iErr != visa32.VI_SUCCESS)
            {
                iErr = visa32.viRead(m_vi, byteRead, maxCount, out retCount);
                if (iErr != visa32.VI_SUCCESS_MAX_CNT && iErr != visa32.VI_SUCCESS)
                {
                    return false;
                }
                sbRet.Append(System.Text.Encoding.Default.GetString(byteRead));
            }
            return true;
        }

        /*
        public bool WaitForTrig()
        {

            string sRt = "";
            byte[] arrFlag = new byte[256];
            int nReady = 0;
            int iStart = DateTime.Now.Second;
            int iDelayTime = 10;
            while (nReady == 0)
            {
                if (!QueryCmd("*ESR?" + "\n", arrFlag, m_sbErr, false))
                {
                    return false;
                }
                sRt = System.Text.Encoding.Default.GetString(arrFlag);
                nReady = GetErrNo(sRt);
                if (DateTime.Now.Second - iStart > iDelayTime)
                {
                    break;
                    return false;
                }
            }
            return true;
        }*/

        public bool SetTraceCoun(int iTraceCount)
        {
            if (m_isDebug) return true;
            if (iTraceCount > 4 || iTraceCount < 1)
            {
                m_sbErr.Append("Invalid Trace Count");
                return false;
            }
            m_sbErr.Length = 0;
            m_sbErr.Append("SetMeasType:");
            if (!SendCmd("CALC1:PAR:COUN " + iTraceCount + "\n", m_sbErr, false))
                return false;
            //display
            string sDisplay = "D";
            for (int i = 0; i < iTraceCount; i++)
            {
                sDisplay += i + 1;
                if (i == 1)
                {
                    sDisplay += "_";
                }
            }
            return SendCmd(":DISP:WIND:SPL " + sDisplay + "\n", m_sbErr, false);
        }

        public bool SetMeasType(int iTraceNo, string inputSparam)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetMeasType:");
            return SendCmd("CALC" + chanNo.ToString() + ":PAR" + iTraceNo.ToString() + ":DEF " + inputSparam + "\n", m_sbErr, true);
        }

        public bool SetFrequency(float f_start, float f_stop)
        {//设置起止频率
            if (m_isDebug) return true;
            //原来这个函数的默认单位是MHz，但是在处理GHz时有bug,现在统一改为Hz
            //f_start = f_start * 1000000;
            //f_stop = f_stop * 1000000;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetFrequency:");
            if (!SendCmd("SENS" + chanNo.ToString() + ":FREQ:STAR " + f_start.ToString() + "\n", m_sbErr, true))
            {
                return false;
            }
            if (!SendCmd("SENS" + chanNo.ToString() + ":FREQ:STOP " + f_stop.ToString() + "\n", m_sbErr, true))
            {
                return false;
            }
            return true;
        }

        void SetAutoScale()
        {
            if (m_isDebug) return;
            int iErr;
            iErr = visa32.viPrintf(m_vi, "DISP:WIND" + chanNo.ToString() + ":TRAC" + m_traceNo.ToString() + ":Y:AUTO" + "\n");
        }

        public bool TraceSel(int iTraceNo)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("TraceSel:");
            return SendCmd("CALC1:PAR" + iTraceNo.ToString() + ":SEL" + "\n", m_sbErr, false);
        }

        public bool SetDisplayFormat(int iTraceNo, string disp)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetDisplayFormat:");
            if (!SendCmd("CALC" + chanNo.ToString() + ":PAR" + iTraceNo.ToString() + ":SEL" + "\n", m_sbErr, true))
            {
                return false;
            }
            if (!SetDisplayFormatOnly(iTraceNo, disp))
                return false;
            return true;
        }

        public bool SetDisplayFormatOnly(int iTraceNo, string disp)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetDisplayFormatOnly:");
            string sCmd = "";
            switch (disp)
            {
                case "DISP_LOGM":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM MLOG" + "\n";
                    break;
                case "DISP_PHAS":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM PHAS" + "\n";
                    break;
                case "DISP_DELA":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM GDEL" + "\n";
                    break;
                case "DISP_SMIC":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM SMIT" + "\n";
                    break;
                case "DISP_POLA":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM POL" + "\n";
                    break;
                case "DISP_LINM":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM MLIN" + "\n";
                    break;
                case "DISP_REAL":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM REAL" + "\n";
                    break;
                case "DISP_IMAG":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM IMAG" + "\n";
                    break;
                case "DISP_SWR":
                    sCmd = "CALC" + chanNo.ToString() + ":FORM SWR" + "\n";
                    break;
                default:
                    m_sbErr.Append("unKnown format cmd!");
                    return false;
            }
            if (!SendCmd(sCmd, m_sbErr, true))
            {
                return false;
            }
            return true;
        }

        //BUS模式设置
        public bool SetSingleSweep()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetSingleSweep:");
            if (!SendCmd("INIT" + chanNo.ToString() + ":CONT ON" + "\n", m_sbErr, false))
            {
                return false;
            }
            if (!SendCmd("TRIG:SOUR BUS" + "\n", m_sbErr, false))
            {
                return false;
            }
            if (!SendCmd("TRIG:SING" + "\n", m_sbErr, true))
            {
                return false;
            }
            return true;


        }

        public bool GetSmooth(ref int iSmooth)
        {//得到trace 里面的smoothing 状态
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetSmooth:");
            byte[] buf = new byte[256];
            if (!QueryCmd(":CALC1:SMO?", buf, m_sbErr, false))
            {
                return false;
            }
            string sSmooth = System.Text.Encoding.Default.GetString(buf);
            iSmooth = (int)Convert.ToSingle(sSmooth);
            return true;
        }

        public bool SetSmooth(string sSmooth)
        {//trace 里面的smoothing
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetSmooth:");
            return SendCmd(":CALC1:SMO " + sSmooth + "\n", m_sbErr, false);
        }

        public bool SetMark(string markMode, float markValue, int markNo)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetMark:");
            if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":ACT" + "\n", m_sbErr, false))
            {
                return false;
            }
            switch (markMode)
            {
                case "MKR_NORMAL":
                    break;
                case "MKR_FREQ":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":X " + markValue.ToString() + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_MAX":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":FUNC:TYPE MAX" + "\n", m_sbErr, true))
                    {
                        return false;
                    }
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":FUNC:EXEC" + "\n", m_sbErr, true))
                    {
                        return false;
                    }
                    break;
                case "MKR_MIN":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":FUNC:TYPE MIN" + "\n", m_sbErr, true))
                    {
                        return false;
                    }
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":FUNC:EXEC" + "\n", m_sbErr, true))
                    {
                        return false;
                    }
                    break;
                case "MKR_DELTA_ON":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:REF ON" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_DELTA_OFF":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:REF OFF" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_WIDTH_ON":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":BWID:THR " + markValue.ToString() + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:BWID ON" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_WIDTH_OFF":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:BWID OFF" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_STAT_ON":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:MATH:STAT ON" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_STAT_OFF":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK:MATH:STAT OFF" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;
                case "MKR_OFF":
                    if (!SendCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + " OFF" + "\n", m_sbErr, false))
                    {
                        return false;
                    }
                    break;

            }
            return true;
        }

        public bool GetMarkYValue(out float markYvalue, int markNo)
        {
            if (m_isDebug)
            {
                markYvalue = 60 + (float)new Random(Guid.NewGuid().GetHashCode()).NextDouble();
                Thread.Sleep(50);
                return true;
            }

            //StringBuilder sbErr = new StringBuilder(512);
            StringBuilder sMarkVal = new StringBuilder();
            markYvalue = 0;
            byte[] buf = new byte[256];
            char[] cbuf = new char[256];
            string[] sArray;
            //int iErr;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetMarkYValue:");


            if (!QueryCmd("CALC" + chanNo.ToString() + ":MARK" + markNo.ToString() + ":Y?", buf, m_sbErr, true))
            {
                return false;
            }

            for (int i = 0; i < 256; i++)
            {
                cbuf[i] = (char)buf[i];
            }
            sMarkVal.Append(cbuf);
            sArray = sMarkVal.ToString().Split(',');
            markYvalue = Convert.ToSingle(sArray[0]);   // 'If UBound(sArray) > 1 Then
            return true;
        }

        public bool GetMarkFuncDomState()
        {//Marker Search > Search Range > Search Range [ON/OFF]
            if (m_isDebug)
                return true;
            byte[] buf = new byte[256];
            m_sbErr.Length = 0;
            m_sbErr.Append("GetMarkFuncDomState:");
            if (!QueryCmd(":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM?\n", buf, m_sbErr, false))
            {
                return false;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            if (sRt == "1")
                return true;
            else
                return false;
        }

        public bool SetMarkFuncDomState(bool isON = true)
        {//Marker Search > Search Range > Search Range [ON/OFF]
            if (m_isDebug)
                return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetMarkFuncDomState:");
            string cmd;
            if (isON)
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM ON\n";
            else
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM OFF\n";
            return SendCmd(cmd, m_sbErr, true);
        }

        public bool GetMarkFuncDomRange(out double f, bool isStart = true)
        {//Marker Search > Search Range > Stop
            f = 0d;
            if (m_isDebug)
                return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetMarkFuncDomRange:");
            string cmd;
            byte[] buf = new byte[256];
            if (isStart)
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM:STARt?\n";
            else
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM STOP?\n";

            if (!QueryCmd(cmd, buf, m_sbErr, false))
            {
                return false;
            }

            string sRt = System.Text.Encoding.Default.GetString(buf);
            f = Convert.ToDouble(sRt);
            return SendCmd(cmd, m_sbErr, false);
        }

        public bool SetMarkFuncDomRange(double f, bool isStart = true)
        {//Marker Search > Search Range > Stop
            if (m_isDebug)
                return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetMarkFuncDomRange:");
            string cmd;
            if (isStart)
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM:STARt " + f + "\n";
            else
                cmd = ":CALC" + chanNo.ToString() + ":MARK:FUNC:DOM:STOP " + f + "\n";
            return SendCmd(cmd, m_sbErr, true);
        }

        public bool SetContSweep()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetContSweep:");
            if (!SendCmd("TRIG:SOUR INT" + "\n", m_sbErr, false))
            { return false; }
            if (!SendCmd("INIT" + chanNo.ToString() + ":CONT ON" + "\n", m_sbErr, false))
            { return false; }
            return true;
        }

        public bool ResetInstr()
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("ResetInstr:");
            return SendCmd(":SYST:PRES\n", m_sbErr, false);//":SYST:PRES\n"  *RST\n

        }

        void CloseInstr()
        {
            if (m_isDebug) return;
            int iErr = visa32.viPrintf(m_vi, "*CLS" + ";" + "\n");
        }

        public bool InstrLock(bool bLock)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("InstrLock:");
            string sOnOff = "";
            if (bLock)
            {
                sOnOff = "ON";
            }
            else
            {
                sOnOff = "OFF";
            }
            if (!SendCmd("SYST:KLOC:KBD " + sOnOff + "\n", m_sbErr, false))
            {
                return false;
            }
            if (!SendCmd("SYST:KLOC:MOUS " + sOnOff + "\n", m_sbErr, false))
            {
                return false;
            }
            return true;

            /*
            int iErr;
            if (bLock)
            {
                iErr = visa32.viPrintf(m_vi, "SYST:KLOC:KBD ON" + "\n");
                iErr = visa32.viPrintf(m_vi, "SYST:KLOC:MOUS ON" + "\n");
            }
            else
            {
                iErr = visa32.viPrintf(m_vi, "SYST:KLOC:KBD OFF" + "\n");
                iErr = visa32.viPrintf(m_vi, "SYST:KLOC:MOUS OFF" + "\n");
            }*/
        }

        public bool SetSweepType(string sType)
        {//sType://"LIN"             //"LOG"            //"SEGM"            //"POW"
            /*Sweep Setup > Sweep Type > Lin Freq|Log Freq|Segment
                扫描设置 > 扫描类型 > 线性频率|对数频率|分段
             */
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetSweepType:");
            return SendCmd(":SENS" + chanNo.ToString() + ":SWE:TYPE " + sType + "\n", m_sbErr, false);
        }

        public bool GetSweepPoints(ref int numPoints)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetSweepPoints:");
            byte[] buf = new byte[256];
            if (!QueryCmd("SENS1:SWE:POIN?", buf, m_sbErr, false))
            {
                return false;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            numPoints = (int)Convert.ToSingle(sRt);
            return true;
        }

        public bool SetSweepPoints(int numPoints)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetSweepPoints:");
            return SendCmd("SENS" + chanNo.ToString() + ":SWE:POIN " + numPoints.ToString() + "\n", m_sbErr, true);
        }

        public bool GetIFBW(ref int iBandwidth)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetIFBW:");
            byte[] buf = new byte[256];
            if (!QueryCmd("SENS1:BWID?", buf, m_sbErr, false))
            {
                return false;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            iBandwidth = (int)Convert.ToSingle(sRt);
            return true;
        }

        public bool SetIFBandWidth(int dbBandwidth)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetIFBandWidth:");
            if (!SendCmd("SENS" + chanNo.ToString() + ":BWID " + dbBandwidth.ToString() + "\n", m_sbErr, false))
            {
                return false;
            }
            /*//读取实际需要的时间
            byte[] buf = new byte[256];
            if (!QueryCmd(":SENS1:SWE:TIME?", buf, m_sbErr, true))
            {
                return false;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            float fTime = Convert.ToSingle(sRt);
            int iDelayTime = (int)(fTime * 1000.0);
            //Thread.Sleep(iDelayTime*2);//进行延时

            //清除标志
            if (!SendCmd("*CLS" + "\n", m_sbErr, false))
            {
                return false;
            }
            //先触发
            if (!SendCmd("TRIG:SING" + "\n", m_sbErr, true))
            {
                return false;
            }
            byte[] arrFlag = new byte[256];
            int nReady = 0;
            int iStart = DateTime.Now.Second;
            while (nReady==0)
            {
                if (!QueryCmd("*ESR?" + "\n",arrFlag, m_sbErr, false))
                {
                    return false;
                }
                sRt = System.Text.Encoding.Default.GetString(arrFlag);
                nReady = GetErrNo(sRt);
                if (DateTime.Now.Second - iStart > iDelayTime * 3)
                {
                    break;
                }
            }*/
            return true;
        }

        public bool GetPower(ref int iPower)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetPower:");
            byte[] buf = new byte[256];
            if (!QueryCmd("SOUR1:POW ?", buf, m_sbErr, false))
            {
                return false;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            iPower = (int)Convert.ToSingle(sRt);
            return true;
        }

        public bool SetPower(int powLevel)
        {
            if (m_isDebug) return true;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetPower:");
            string sCmd = "";
            if (powLevel >= -5 && powLevel <= 10)
            {
                sCmd = ":POW:ATT 0";
            }
            else if (powLevel >= -15 && powLevel < -5)
            {
                sCmd = ":POW:ATT 10";
            }
            else if (powLevel >= -25 && powLevel < -15)
            {
                sCmd = ":POW:ATT 20";
            }
            else if (powLevel >= -35 && powLevel < -25)
            {
                sCmd = ":POW:ATT 30";
            }
            else if (powLevel >= -45 && powLevel < -35)
            {
                sCmd = ":POW:ATT 40";
            }
            else
            {
                sCmd = ":POW:ATT 40";
            }
            if (!SendCmd("SOUR" + chanNo.ToString() + sCmd + "\n", m_sbErr, false))
            {
                return false;
            }
            if (!SendCmd("SOUR" + chanNo.ToString() + ":POW " + powLevel.ToString() + "\n", m_sbErr, false))
            {
                return false;
            }
            return true;


            /*
            int iErr;
            if (powLevel >= -5 && powLevel <= 10)
            {
                //SetPowerRange(" PWR_RANGE_N05_P10", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 0" + "\n");
            }
            else if (powLevel >= -15 && powLevel < -5)
            {
                //SetPowerRange("PWR_RANGE_N15_P00", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 10" + "\n");
            }
            else if (powLevel >= -25 && powLevel < -15)
            {
                //SetPowerRange("PWR_RANGE_N25_N10", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 20" + "\n");
            }
            else if (powLevel >= -35 && powLevel < -25)
            {
                //SetPowerRange("PWR_RANGE_N35_N20", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 30" + "\n");
            }
            else if (powLevel >= -45 && powLevel < -35)
            {
                //SetPowerRange("PWR_RANGE_N45_N30", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 40" + "\n");
            }
            else
            {
                //SetPowerRange(" PWR_RANGE_N45_N30", chanNo);
                iErr = visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW:ATT 40" + "\n");
            }

            visa32.viPrintf(m_vi, "SOUR" + chanNo.ToString() + ":POW " + powLevel.ToString() + "\n");*/

        }

        public bool SetCalFor1Port(int portNo)
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor1Port:");
            return SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:METH:SOLT1" + " " + portNo.ToString() + "\n", m_sbErr, false);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public bool SetCalFor2Port()
        {
            //int iErr = visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:METH:SOLT2 " + " 1,2" + "\n");
            //'SOLT1 1-PortCal SOLT2 2-PortCal
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Port:");
            return SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:METH:SOLT2 " + " 1,2" + "\n", m_sbErr, false);

        }

        public void SetCalFor2Open1()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Open1:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:OPEN " + " 1" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:OPEN " + " 1" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Shor1()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Shor1:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:SHOR " + " 1" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:SHOR " + " 1" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Load1()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Load1:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:LOAD " + " 1" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:LOAD " + " 1" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Open2()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Open2:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:OPEN " + " 2" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:OPEN " + " 2" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Shor2()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Shor2:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:SHOR " + " 2" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:SHOR " + " 2" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Load2()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Load2:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:LOAD " + " 2" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:LOAD " + " 2" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Thru1()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Thru1:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:THRU " + " 1,2" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:THRU " + " 1,2" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Thru2()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Thru2:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:THRU " + " 2,1" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:THRU " + " 2,1" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Isol1()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Isol1:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:ISOL " + " 2,1" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:ISOL " + " 2,1" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Isol2()
        {
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCalFor2Isol2:");
            //visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:ISOL " + " 1,2" + "\n");
            bool bRet = SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:ISOL " + " 1,2" + "\n", m_sbErr, true);
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetCalFor2Save()
        {
            //'        Dim B As Long

            //'        viPrintf m_vi, "SENS" & CStr(chanNo) & ":CORR:COLL:SAVE " & "" & "\n", 0

            //'        B = viPrintf(m_vi, "SENS" & CStr(chanNo) & ":CORR:COLL:SAVE " & "" & "\n")
            //'
            //'        TimeDelay 1.5
            //'
            //'        CheckError B

            visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":CORR:COLL:SAVE " + "" + "\n");
            //'SOLT1 1-PortCal SOLT2 2-PortCal
        }

        public void SetAverageOn(float averageNum)
        {
            if (m_isDebug) return;
            if (averageNum == 0)
            {
                visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":AVER:STAT OFF" + "\n");
            }
            else
            {
                visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":AVER:COUN " + averageNum.ToString() + "\n");
                visa32.viPrintf(m_vi, "SENS" + chanNo.ToString() + ":AVER:STAT ON" + "\n");
            }
        }

        public void SetCoolCkit(int index)
        {/*设置校准件型号(仅安捷伦校准件)，index range 1-20   :SENS1:CORR:COLL:CKIT 3  */
            if (m_isDebug) return;
            m_sbErr.Length = 0;
            m_sbErr.Append("SetCoolCkit:");
            SendCmd("SENS" + chanNo.ToString() + ":CORR:COLL:CKIT " + index.ToString() + "\n", m_sbErr, false);
        }
        public int GetCollCkit()
        {/*获取校准件选择的型号 index 1-20  :SENS1:CORR:COLL:CKIT?*/
            if (m_isDebug) return 3;
            m_sbErr.Length = 0;
            m_sbErr.Append("GetCollCkit:");
            byte[] buf = new byte[256];
            if (!QueryCmd(":SENS1:CORR:COLL:CKIT?", buf, m_sbErr, false))
            {
                return -1;
            }
            string sRt = System.Text.Encoding.Default.GetString(buf);
            return Convert.ToInt32(sRt);
        }


    }


    public class clsVNA_5062A : clsBaseVNA
    {

        public clsVNA_5062A(string sType)
        {
            m_sClsType = sType;
        }

        public override void Dothings()
        {
            Console.WriteLine("this is in clsVNA_5062A.");
        }
    }

    public class clsVNA_5071B : clsBaseVNA
    {
        public clsVNA_5071B(string sType)
        {
            m_sClsType = sType;
        }

        public override void Dothings()
        {
            Console.WriteLine("this is in clsVNA_5071B.");
        }
    }
    public class clsVNA_5061B : clsBaseVNA
    {
        public clsVNA_5061B(string sType)
        {
            m_sClsType = sType;
        }

        public override void Dothings()
        {
            Console.WriteLine("this is in clsVNA_5071B.");
        }
    }

    public class clsVNA_5071C : clsBaseVNA
    {
        public clsVNA_5071C(string sType)
        {
            m_sClsType = sType;
        }
        public override void Dothings()
        {
            Console.WriteLine("this is in clsVNA_5071C.");
        }
    }
}
